package com.yanggu.scala.chapater10

object TupleDemo01 {

  def main(args: Array[String]): Unit = {
    //1. 快速体验下元祖
    //元祖可以在对应索引处定义泛型
    val tuple = (1, 2, 3, "Hello", 4, Person("张三", 20), (1, 2, 3))
    println(tuple)

    //2. 元祖可以理解为一个容器, 类似于类。可以存放多个数据。元祖中最大只能有22个元素

    //3. 元祖的创建语法。使用()包起来, 中间可以存放任意的数据类型
    //根据元素的个数有Tuple1 -- Tuple22

    //4. 元祖的访问和遍历
    println("*****************元祖的遍历*****************")
    //元祖的访问使用变量名._索引开始。索引从1开始, 并不是从0开始, 这点要特别注意
    println(tuple._1)

    println()
    //tuple._1 = "张三" 元祖只能访问, 不能重新赋值
    //元祖是只读的, 不能重新赋值
    tuple.productIterator.foreach(println)

    //元祖的使用场景非常有限。目前的场景只有在返回值有多个, 需要使用一种数据结构进行封装
    //在大数据领域使用地较多, 一般是将list的数据集转换成元祖
    //之前使用case class返回, 现在可以使用元祖代替
    println(tupleFun("张三", 20))

    def tupleFun(name: String, age: Int) = {
      (name, age)
    }

    //5. 解构元祖
    val tuple2 = ("Sugar", 20)
    val (name, age) = tuple2
    println(s"name: $name, age: $age")

    //6. 模式匹配中匹配元祖
    val planetDistanceFromSun = List(("Mercury", 57.9), ("Venus", 108.2), ("Earth", 149.6), ("Mars", 227.9), ("Jupiter", 778.3))

    planetDistanceFromSun.foreach { tuple => {
        tuple match {
          case ("Mercury", distance) => println(s"Mercury is $distance millions km far from Sun")
          case p if (p._1 == "Venus") => println(s"Venus is ${p._2} millions km far from Sun")
          case p if (p._1 == "Earth") => println(s"Blue planet is ${p._2} millions km far from Sun")
          case _ => println("Too far....")
        }
      }
    }

    //7. for循环中匹配元祖
    val numPairs = List((2, 5), (3, -7), (20, 56))
    for ((a, b) <- numPairs) {
      println(a * b)
    }

  }

}

class Person(var name: String, var age: Int) {

  override def toString = s"Person(name=$name, age=$age)"

}

object Person {

  def apply(name: String, age: Int): Person = new Person(name, age)

}
